﻿namespace Bean.Entity.Dto.PolicyPushDto;

/// <summary>
/// 同程政策通用通行字段
/// 普通和特殊政策都能用单独抽离出来
/// </summary>
public class OtaLyBasicPolicyPushDto
{
    /// <summary>
    /// 
    /// </summary>
    protected OtaLyBasicPolicyPushDto()
    {
        
        
    }
    
    
    /// <summary>
    /// 政策代码
    /// </summary>
    public string policyCode { get; private set; }

    /// <summary>
    /// 政策代码扩展字段
    /// </summary>
    public string policyCodeExtend { get;private set; }

    /// <summary>
    /// 政策是否有效
    /// </summary>
    public int isValid { get;private set; }

    /// <summary>
    /// 是否共享航班
    /// </summary>
    public int isApplyShareFlight { get; private set; }

    /// <summary>
    /// 是否代订位
    /// </summary>
    public int isAgentBooking { get; private set; }

    /// <summary>
    /// 代订位失败处理方式
    /// </summary>
    public int agentBookFailType { get; private set; }

    /// <summary>
    /// AV余位阈值
    /// </summary>
    public int? seatLimit { get; private set; }

    /// <summary>
    /// AV大于此值可售
    /// </summary>
    public int? avEffectiveSaleValue { get;private set; }

    /// <summary>
    /// 报销类型
    /// </summary>
    public int reimbursementType { get;private set; }

    /// <summary>
    /// 触发代订位，需要使用的 office 号
    /// </summary>
    public string? officeNo { get;private set; }

    /// <summary>
    /// 客票解析，需要使用的 office 号
    /// </summary>
    public string analyzeTicketOfficeNo { get;private set; }

    /// <summary>
    /// 航司针对给指定代理人的特殊政策的三方协议代码
    /// </summary>
    public string? bigClientCode { get;private set; }

    /// <summary>
    /// 资源适用场景
    /// 4-联程场景、11-拼接假联程；
    /// </summary>
    public List<int> resourceApplySceneList { get;private set; }

    /// <summary>
    /// 联程组合限制
    /// </summary>
    public string transitConfig { get;private set; }

    /// <summary>
    /// 行程类型
    /// </summary>
    public int tripType { get;private set; }

    /// <summary>
    /// 航司二字代码
    /// </summary>
    public string airCompany { get;private set; }

    /// <summary>
    /// 出发机场三字代码
    /// </summary>
    public string startPort { get;private set; }

    /// <summary>
    /// 抵达机场三字代码
    /// </summary>
    public string endPort { get;private set; }

    /// <summary>
    /// 适用舱位代码
    /// </summary>
    public string[] cabinCodeList { get;private set; }

    /// <summary>
    /// 航班限制
    /// </summary>
    public int flightNoFit { get;private set; }

    /// <summary>
    /// 航班号列表
    /// </summary>
    public string[] flightNoList { get;private set; }

    /// <summary>
    /// 适用星期数
    /// </summary>
    public List<int> weekSegmentList { get;private set; }

    /// <summary>
    /// 政策适用起飞开始时间
    /// </summary>
    public string startDate { get;private set; }

    /// <summary>
    /// 政策适用起飞截止时间
    /// </summary>
    public string endDate { get;private set; }

    /// <summary>
    /// 起飞适用时间
    /// </summary>
    public string applyTimeRangeSegment { get;private set; }

    /// <summary>
    /// 不适用航班日期
    /// </summary>
    public string notFlightDate { get;private set; }

    /// <summary>
    /// 销售起始日期
    /// </summary>
    public string startSellDate { get;private set; }

    /// <summary>
    /// 销售结束日期
    /// </summary>
    public string endSellDate { get;private set; }

    /// <summary>
    /// N天内，表示最早提前销售的天数
    /// </summary>
    public int startSaleDay { get;private set; }

    /// <summary>
    /// N时刻开始销售
    /// </summary>
    public string startSaleTime { get;private set; }

    /// <summary>
    /// N天外，表示最晚提前销售天数
    /// </summary>
    public int endSaleDay { get;private set; }

    /// <summary>
    /// N时刻停止销售
    /// </summary>
    public string endSaleTime { get;private set; }

    /// <summary>
    /// 销售开始时间
    /// </summary>
    public string startSaleApplyTime { get;private set; }

    /// <summary>
    /// 销售结束时间
    /// </summary>
    public string endSaleApplyTime { get;private set; }

    /// <summary>
    /// 销售适用时间段
    /// </summary>
    public string saleApplyTimeRangeSegment { get;private set; }

    /// <summary>
    /// 成人政策返点比例
    /// </summary>
    public decimal adultRebatePercent { get;private set; }

    /// <summary>
    /// 成人政策返点金额
    /// </summary>
    public decimal adultRebateMoney { get;private set; } // 成人政策返点金额

    /// <summary>
    /// 儿童政策返点比例
    /// </summary>
    public decimal childRebatePercent { get;private set; }

    /// <summary>
    /// 儿童政策返点金额
    /// </summary>
    public decimal childRebateMoney { get;private set; }

    /// <summary>
    /// 竞价金额
    /// </summary>
    public decimal keepMoney { get;private set; }

    /// <summary>
    /// 竞价比例
    /// </summary>
    public decimal keepMoneyPercent { get;private set; }

    /// <summary>
    /// 销售类型；
    /// 普通政策目前均是1-AV有座销售；
    /// </summary>
    public int sellType { get;private set; } // 销售类型

    /// <summary>
    /// 备注
    /// </summary>
    public string remark { get;private set; }

    /// <summary>
    /// 是否出主承运
    /// </summary>
    public int carryVerifyCabinPrice { get;private set; }

    /// <summary>
    /// 主承运航司
    /// </summary>
    public string carryAirCompany { get;private set; }

    /// <summary>
    /// 每日可售库存数
    /// </summary>
    public int? everydayInventory { get;private set; }

    /// <summary>
    /// 改期代订位AV余位阈值 
    /// </summary>
    public int rebookSeatLimit { get;private set; }

    /// <summary>
    /// 儿童与成人同价
    /// </summary>
    public int isChildEqAdultPrice { get;private set; } // 儿童与成人同价

    /// <summary>
    /// 
    /// </summary>
    public class Builder
    {
        protected OtaLyBasicPolicyPushDto _dto = new OtaLyBasicPolicyPushDto();

        /// <summary>
        /// 设置政策编码
        /// </summary>
        /// <param name="policyCode"></param>
        /// <returns></returns>
        public Builder SetPolicyCode(string policyCode)
        {
            _dto.policyCode = policyCode;
            return this;
        }

        /// <summary>
        /// 设置政策编码扩展
        /// </summary>
        /// <param name="policyCodeExtend"></param>
        /// <returns></returns>
        public Builder SetPolicyCodeExtend(string policyCodeExtend)
        {
            _dto.policyCodeExtend = policyCodeExtend;
            return this;
        }

        /// <summary>
        /// 枚举：0-无效、1-有效 ；
        /// </summary>
        /// <param name="isValid">默认有效</param>
        /// <returns></returns>
        public Builder SetIsValid(int isValid = 1)
        {
            _dto.isValid = isValid;
            return this;
        }

        /// <summary>
        /// 是否共享航班
        ///  默认(0-否)； 枚举：0-否、1-是；
        /// </summary>
        /// <param name="isApplyShareFlight"></param>
        /// <returns></returns>
        public Builder SetIsApplyShareFlight(int isApplyShareFlight = 0)
        {
            _dto.isApplyShareFlight = isApplyShareFlight;
            return this;
        }

        /// <summary>
        /// 是否代订位
        /// 默认(0-否)； 枚举：0-否、1-是；
        /// </summary>
        /// <param name="isAgentBooking"></param>
        /// <returns></returns>
        public Builder SetIsAgentBooking(int isAgentBooking = 0)
        {
            _dto.isAgentBooking = isAgentBooking;
            return this;
        }

        /// <summary>
        /// 代订位失败类型
        /// 默认(0-拦截下单)； 枚举：0-拦截下单、1-收单；
        /// </summary>
        /// <param name="agentBookFailType"></param>
        /// <returns></returns>
        public Builder SetAgentBookFailType(int agentBookFailType = 0)
        {
            _dto.agentBookFailType = agentBookFailType;
            return this;
        }

        /// <summary>
        /// AV余位阈值
        /// 默认(字段不生效)； 生效范围[1-9]，AV余位小于当前指定值才会代订位；
        /// </summary>
        /// <param name="seatLimit"></param>
        /// <returns></returns>
        public Builder SetSeatLimit(int? seatLimit)
        {
            _dto.seatLimit = seatLimit;
            return this;
        }

        /// <summary>
        /// AV大于此值可售
        /// </summary>
        /// <param name="avEffectiveSaleValue"></param>
        /// <returns></returns>
        public Builder SetAvEffectiveSaleValue(int? avEffectiveSaleValue)
        {
            _dto.avEffectiveSaleValue = avEffectiveSaleValue;
            return this;
        }

        /// <summary>
        /// 报销类型
        /// 默认( 0-行程单)； 枚举： 0-行程单、1-服务发票； 共享航班出主承运必须为1-服务发票
        /// </summary>
        /// <returns></returns>
        public Builder SetReimbursementType(int reimbursementType = 0)
        {
            _dto.reimbursementType = reimbursementType;
            return this;
        }

        /// <summary>
        /// 触发代订位
        /// </summary>
        /// <param name="officeNo"></param>
        /// <returns></returns>
        public Builder SetOfficeNo(string? officeNo)
        {
            _dto.officeNo = officeNo;
            return this;
        }

        /// <summary>
        /// 客票解析，需要使用的 office 号
        /// </summary>
        /// <returns></returns>
        public Builder SetAnalyzeTicketOfficeNo(string analyzeTicketOfficeNo)
        {
            _dto.analyzeTicketOfficeNo = analyzeTicketOfficeNo;
            return this;
        }

        /// <summary>
        /// 航司针对给指定代理人的特殊政策的三方协议代码
        /// </summary>
        /// <returns></returns>
        public Builder SetBigClientCode(string? bigClientCode)
        {
            _dto.bigClientCode = bigClientCode;
            return this;
        }

        /// <summary>
        /// 资源适用场景
        /// 枚举：4-联程场景、11-拼接假联程；
        /// </summary>
        /// <param name="resourceApplySceneList"></param>
        /// <returns></returns>
        public Builder SetResourceApplySceneList(List<int> resourceApplySceneList)
        {
            _dto.resourceApplySceneList = resourceApplySceneList;
            return this;
        }

        /// <summary>
        /// 联程组合限制
        /// </summary>
        /// <param name="transitConfig"></param>
        /// <returns></returns>
        public Builder SetTransitConfig(string transitConfig)
        {
            if ((_dto.resourceApplySceneList.Contains(4) || _dto.resourceApplySceneList.Contains(11)) && string
                    .IsNullOrWhiteSpace(transitConfig))
            {
                throw new InvalidDataException("资源适用场景 选择联程场景/或者拼接假联程时 联程组合限制必填");
            }

            _dto.transitConfig = transitConfig;
            return this;
        }

        /// <summary>
        /// 必有字段  备注：行程类型； 枚举：1-单程
        /// </summary>
        /// <param name="tripType"></param>
        /// <returns></returns>
        public Builder SetTripType(int tripType = 1)
        {
            _dto.tripType = tripType;
            return this;
        }

        /// <summary>
        /// 航空公司二字代码 2 位大写字母
        /// </summary>
        /// <param name="airCompany"></param>
        /// <returns></returns>
        public Builder SetAirCompany(string airCompany)
        {
            if (string.IsNullOrWhiteSpace(airCompany))
            {
                throw new InvalidDataException("航空公司二字代码 必填");
            }

            _dto.airCompany = airCompany;
            return this;
        }

        /// <summary>
        /// 出发城市三字码
        /// </summary>
        /// <param name="startPort"></param>
        /// <returns></returns>
        public Builder SetStartPort(string startPort)
        {
            if (string.IsNullOrWhiteSpace(startPort))
            {
                throw new InvalidDataException("出发城市三字码 必填");
            }

            _dto.startPort = startPort;
            return this;
        }

        /// <summary>
        /// 到达城市三字码
        /// </summary>
        /// <param name="endPort"></param>
        /// <returns></returns>
        public Builder SetEndPort(string endPort)
        {
            if (string.IsNullOrWhiteSpace(endPort))
            {
                throw new InvalidDataException("到达城市三字码 必填");
            }

            _dto.endPort = endPort;
            return this;
        }

        /// <summary>
        /// 适用的舱位代码
        /// </summary>
        /// <param name="cabinCodeList"></param>
        /// <returns></returns>
        /// <exception cref="InvalidDataException"></exception>
        public Builder SetCabinCodeList(string[] cabinCodeList)
        {
            if (cabinCodeList == null || cabinCodeList.Length == 0)
            {
                throw new InvalidDataException("舱位代码 必填");
            }

            _dto.cabinCodeList = cabinCodeList;
            return this;
        }

        /// <summary>
        /// 航班限制
        /// 默认0-=所有航班均适用； 枚举：0-所有航班均适用、 1-部分航班适用 、2-部分航班不适用；
        /// </summary>
        /// <param name="flightNoFit"></param>
        /// <returns></returns>
        public Builder SetFlightNoFit(int flightNoFit = 0)
        {
            _dto.flightNoFit = flightNoFit;
            return this;
        }

        /// <summary>
        /// 航班号
        /// 当“flightNoFit =0 ”时，FlightNoList 不传；
        /// 当“flightNoFit !=0 ”时，必传航班号 ； 每个航班号必须6到7位由字母数字组成； 航班号个数不超过100； 例：["CA3463","CA5234","CA2343"]
        /// </summary>
        /// <param name="flightNoList"></param>
        /// <returns></returns>
        public Builder SetFlightNoList(string[] flightNoList)
        {
            if (_dto.flightNoFit == 0)
            {
                _dto.flightNoList = [];
            }
            else if (_dto.flightNoFit != 0 && flightNoList.Length == 0)
            {
                throw new InvalidDataException(" 航班限制不为0/航班均适用. 航班号必填");
            }

            _dto.flightNoList = flightNoList;
            return this;
        }

        /// <summary>
        /// 适用星期数
        /// </summary>
        /// <returns></returns>
        public Builder SetWeekSegmentList(List<int> weekSegmentList = null)
        {
            _dto.weekSegmentList = weekSegmentList ?? new List<int> { 1, 2, 3, 4, 5, 6, 7 };
            return this;
        }

        /// <summary>
        /// 政策适用起飞开始时间
        /// </summary>
        /// <param name="startDate"></param>
        /// <returns></returns>
        public Builder SetStartDate(string startDate)
        {
            if (string.IsNullOrWhiteSpace(startDate))
            {
                throw new InvalidDataException("开始日期 必填");
            }

            _dto.startDate = startDate;
            return this;
        }

        /// <summary>
        /// 政策适用起飞结束时间
        /// </summary>
        /// <param name="endDate"></param>
        /// <returns></returns>
        /// <exception cref="InvalidDataException"></exception>
        public Builder SetEndDate(string endDate)
        {
            if (string.IsNullOrWhiteSpace(endDate))
            {
                throw new InvalidDataException("结束日期 必填");
            }

            _dto.endDate = endDate;
            return this;
        }

        /// <summary>
        /// 起飞适用时间
        /// 格式：00:00-10:00,12:00-20:00
        /// </summary>
        /// <param name="applyTimeRangeSegment"></param>
        /// <returns></returns>
        /// <exception cref="InvalidDataException"></exception>
        public Builder SetApplyTimeRangeSegment(string applyTimeRangeSegment)
        {
            _dto.applyTimeRangeSegment = applyTimeRangeSegment;
            return this;
        }

        /// <summary>
        /// 不适用航班日期
        /// </summary>
        /// <param name="notFlightDate"></param>
        /// <returns></returns>
        public Builder SetNotFlightDate(string notFlightDate)
        {
            _dto.notFlightDate = notFlightDate;
            return this;
        }

        /// <summary>
        /// 销售起始日期
        /// </summary>
        /// <returns></returns>
        public Builder SetStartSellDate(string startSellDate)
        {
            if (string.IsNullOrWhiteSpace(startSellDate))
            {
                throw new InvalidDataException("销售起始日期 必填");
            }

            _dto.startSellDate = startSellDate;
            return this;
        }

        /// <summary>
        /// 销售结束日期
        /// </summary>
        /// <param name="endSellDate"></param>
        /// <returns></returns>
        /// <exception cref="InvalidDataException"></exception>
        public Builder SetEndSellDate(string endSellDate)
        {
            if (string.IsNullOrWhiteSpace(endSellDate))
            {
                throw new InvalidDataException("销售结束日期 必填");
            }

            _dto.endSellDate = endSellDate;
            return this;
        }

        /// <summary>
        /// N天内，表示最早提前销售的天数
        /// </summary>
        /// <param name="startSaleDay"></param>
        /// <returns></returns>
        public Builder SetStartSaleDay(int startSaleDay)
        {
            _dto.startSaleDay = startSaleDay;
            return this;
        }

        /// <summary>
        /// N时刻开始销售；默认值"00:00" ；格式：HH:mm 可输入值范围00:00-23:59
        /// </summary>
        /// <returns></returns>
        public Builder SetStartSaleTime(string startSaleTime = "00:00")
        {
            _dto.startSaleTime = startSaleTime;
            return this;
        }

        /// <summary>
        /// N天外，表示最晚提前销售天数
        /// </summary>
        /// <param name="endSaleDay"></param>
        /// <returns></returns>
        public Builder SetEndSaleDay(int endSaleDay = 0)
        {
            _dto.endSaleDay = endSaleDay;
            return this;
        }

        /// <summary>
        /// 默认值"00:00" ；格式：HH:mm 可输入值范围00:00-23:59
        /// </summary>
        /// <param name="endSaleTime"></param>
        /// <returns></returns>
        public Builder SetEndSaleTime(string endSaleTime = "00:00")
        {
            _dto.endSaleTime = endSaleTime;
            return this;
        }

        /// <summary>
        /// 销售适用时间段
        /// </summary>
        /// <param name="saleApplyTimeRangeSegment"></param>
        /// <returns></returns>
        public Builder SetSaleApplyTimeRangeSegment(string saleApplyTimeRangeSegment = "")
        {
            _dto.saleApplyTimeRangeSegment = saleApplyTimeRangeSegment;
            return this;
        }

        /// <summary>
        /// Number  必有字段  备注：成人政策返点比例； 只支持一位小数； 如10%，传10，录入系统后会自动除以100；
        /// </summary>
        /// <returns></returns>
        public Builder SetAdultRebatePercent(int adultRebatePercent = 0)
        {
            _dto.adultRebatePercent = adultRebatePercent;
            return this;
        }

        /// <summary>
        /// 成人政策返点金额； 只支持2位小数输入；
        /// </summary>
        /// <param name="adultRebateMoney"></param>
        /// <returns></returns>
        public Builder SetAdultRebateMoney(decimal adultRebateMoney)
        {
            _dto.adultRebateMoney = adultRebateMoney;
            return this;
        }

        /// <summary>
        /// 儿童政策返点比例； 只支持一位小数； 如10%，传10，录入系统后会自动除以100；
        /// </summary>
        /// <param name="childRebatePercent"></param>
        /// <returns></returns>
        public Builder SetChildRebatePercent(int childRebatePercent = 0)
        {
            _dto.childRebatePercent = childRebatePercent;
            return this;
        }

        /// <summary>
        /// 儿童政策返点金额； 只支持2位小数输入；
        /// </summary>
        /// <param name="childRebateMoney"></param>
        /// <returns></returns>
        public Builder SetChildRebateMoney(decimal childRebateMoney = 0)
        {
            _dto.childRebateMoney = childRebateMoney;
            return this;
        }

        /// <summary>
        /// 竞价金额
        /// </summary>
        /// <param name="keepMoney"></param>
        /// <returns></returns>
        public Builder SetKeepMoney(decimal keepMoney = 0)
        {
            _dto.keepMoney = keepMoney;
            return this;
        }

        /// <summary>
        /// 竞价比例； 仅支持大于等于0的两位小数； 如10%，传10，录入系统后会自动除以100，精确到小数点后第二位；
        /// </summary>
        /// <returns></returns>
        public Builder SetKeepMoneyPercent(decimal keepMoneyPercent = 0)
        {
            _dto.keepMoneyPercent = keepMoneyPercent;
            return this;
        }

        /// <summary>
        /// 销售类型； 普通政策目前均是1-AV有座销售；
        /// </summary>
        /// <param name="sellType"></param>
        /// <returns></returns>
        public Builder SetSellType(int sellType)
        {
            _dto.sellType = sellType;
            return this;
        }

        /// <summary>
        /// 备注：备注；字母和数字且字符不得超过50个；
        /// </summary>
        /// <returns></returns>
        public Builder SetRemark(string remark)
        {
            _dto.remark = remark;
            return this;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="resourceApplySceneList"></param>
        /// <returns></returns>
        public Builder SetCarryVerifyCabinPrice(int carryVerifyCabinPrice = 0)
        {
            _dto.carryVerifyCabinPrice = carryVerifyCabinPrice;
            return this;
        }

        /// <summary>
        /// 主承运航司，
        /// 出主承运时必传，其他必须为空
        /// </summary>
        /// <param name="carryAirCompany"></param>
        /// <returns></returns>
        public Builder SetCarryAirCompany(string carryAirCompany)
        {
            _dto.carryAirCompany = carryAirCompany;
            return this;
        }

        /// <summary>
        /// 每日可售库存数：大于等于0整数
        /// </summary>
        /// <param name="everydayInventory"></param>
        /// <returns></returns>
        public Builder SetEverydayInventory(int? everydayInventory)
        {
            _dto.everydayInventory = everydayInventory;
            return this;
        }

        /// <summary>
        /// 改期代订位AV余位阈值；
        /// 默认：0-不代定位 ； 0-不代定位 ；
        /// [1-9]：av余位数小于等于该数字代订位； 10：全部代订位；
        /// </summary>
        /// <param name="rebookSeatLimit"></param>
        /// <returns></returns>
        public Builder SetRebookSeatLimit(int rebookSeatLimit)
        {
            _dto.rebookSeatLimit = rebookSeatLimit;
            return this;
        }

        /// <summary>
        /// 构建方法
        /// </summary>
        /// <returns></returns>
        public virtual OtaLyBasicPolicyPushDto Build()
        {
            return _dto;
        }
    }
}